# -*- coding: utf-8 -*-
import path
from path import Path2
import util
class _Node(object):
    def __init__(self,parent,name,data):
        self._parent=parent
        self._name=name
        self._data=data
        self._children = {}
        
    def isRoot(self):
        return self._parent is None
    
    def getChild(self,name):
        assert self.hasChild(name),"node not exists:%s" % str(self.getPath().append(name))
        return self._children[name]
    
    def getChildren(self):
        return self._children.values()
    
    def getPath(self):
        if self.isRoot():
            return Path2.ROOT
        return self._parent.getPath().append(self._name)
    
    def hasChild(self,name):
        return self._children.has_key(name)

    def addChild(self,name,childData):
        assert not self.hasChild(name)
        self._children[name] = _Node(self,name,childData)
    
class DataTree(object):
    def __init__(self,rootData):
        self._cache = {}
        self._root =_Node(None ,'root', rootData)
        self.add(Path2.ROOT,rootData)
    
    def exists(self,nodePath):
        return self._cache.has_key(nodePath)
    
    def getData(self,nodePath):
        assert self.exists(nodePath)
        return self._cache[nodePath]._data
    
    def getChildrenPath(self,nodePath):
        '''getChildrenPath(self,Path nodePath) -> Path[]'''
        assert nodePath is not None
        assert self.exists(nodePath)
        
        return map(lambda n:n.getPath() , self._cache[nodePath].getChildren())
    
    def add(self,nodePath,nodeData):
        assert nodePath is not None
        assert not self.exists(nodePath)
        
        if nodePath == Path2.ROOT:
            self._cache[nodePath]  = self._root = _Node(None ,'root', nodeData)
        else:
            assert self.exists(nodePath.getParent()),"parent not exists,add parent first:%s" % str(nodePath)
            
            name = nodePath.getLastSegment()
            parent=self._cache[nodePath.getParent()]
            parent.addChild(name,nodeData)
            self._cache[nodePath] = _Node(parent ,name, nodeData)
            
    def update(self,nodePath,newData):
        self._cache[nodePath]._data = newData
   
